package me.zhengjie.modules.workflow.rest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.modules.workflow.service.WorkFlowService;
import me.zhengjie.modules.workflow.vo.ApproveVo;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import me.zhengjie.modules.workflow.vo.ApplyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 工作流控制器
 * @description: ActivitiController <br>
 * @date: 2020/10/18 12:23 <br>
 * @author: wangz <br>
 * @version: 1.0 <br>
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/activiti")
@Api(tags = "工作流：工作流管理")
public class ActivitiController {

    @Autowired
    private WorkFlowService workFlowService;

    @Autowired
    private UserService userService;

    @Log("启动流程")
    @PostMapping("/apply")
    @ApiOperation(value="启动流程")
    public ResponseEntity<Object> startWorkflow(@RequestBody ApplyVo applyVo){
        //模拟传入流程相关参数：1.当前用户  2.相关审批人，前端页面选择传入
        Map param = new HashMap(4){{
            put("applyUserId",SecurityUtils.getCurrentUserId());
            //候选用户集合
            if(applyVo.getApproveUserIds() != null && applyVo.getApproveUserIds().length > 0){
                put("approveUserIds", Arrays.asList(applyVo.getApproveUserIds()));
            }
        }};

        if(StringUtils.isBlank(applyVo.getPdKey())){
            throw new BadRequestException("请传入流程Key");
        }

        // 启动流程：启动流程，传入业务数据外键
        String pdId = workFlowService.startWorkflow(applyVo.getPdKey(), applyVo.getBusinessKey(), param);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("任务审批")
    @PostMapping("/approve")
    @ApiOperation(value="任务审批")
    public ResponseEntity<Object> continueWorkflow(@RequestBody ApproveVo approveVo){

        //审批相关参数：审批人，审批结果：result
        Map param = new HashMap(2){{
            UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
            put("dealUserId",userDto.getId());
            put("result",approveVo.getResult());
        }};

        // 完成当前任务节点
        workFlowService.continueWorkflow(approveVo.getTaskId(),param);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("委托任务")
    @PostMapping("/delegate")
    @ApiOperation(value="委托任务")
    public ResponseEntity<Object> delegateWorkflow(@RequestParam String pId,@RequestParam Long userId){
        Map param = new HashMap(2){{
            UserDto userDto = userService.findById(userId);
            put("dealUserId",userDto.getUsername());
        }};
        // 根据流程ID获取请假审批任务ID
        String Id = workFlowService.getCurrentTask(pId);
        // 完成流程任务委托
        workFlowService.delegateWorkflow(Id,param);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("任务签收")
    @PostMapping("/signFor")
    @ApiOperation(value="任务签收")
    public ResponseEntity<Object> signFor(@RequestBody String taskId){
        Map param = new HashMap(2){{
            UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
            put("dealUserId",userDto.getUsername());
        }};
        workFlowService.signFor(taskId,param);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("流程回退")
    @PostMapping("/rollBack/{taskId}")
    @ApiOperation(value="流程回退")
    public ResponseEntity<Object> rollBack(@PathVariable String taskId){
        workFlowService.rollBack(taskId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("流程拒绝")
    @PostMapping("/reject/{taskId}")
    @ApiOperation(value="流程回退")
    public ResponseEntity<Object> reject(@PathVariable String taskId){
        UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
        workFlowService.reject(taskId,userDto.getUsername());
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("任务指派")
    @PostMapping("/reassignment")
    @ApiOperation(value="任务指派")
    public ResponseEntity<Object> reassignment(String processInstanceId,String roleId, String user){
        workFlowService.reassignment(processInstanceId,roleId,user);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("征询")
    @PostMapping("/inquire/{taskId}")
    @ApiOperation(value="征询")
    public ResponseEntity<Object> inquire(@PathVariable String taskId){
        UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
        List<String> users = new ArrayList<String>();
        workFlowService.inquire(taskId,users,userDto.getUsername());
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Log("征询回应")
    @PostMapping("/reply/{taskId}")
    @ApiOperation(value="征询回应")
    public ResponseEntity<Object> reply(@PathVariable String taskId){
        UserDto userDto = userService.findById(SecurityUtils.getCurrentUserId());
        List<String> users = new ArrayList<String>();
        //workFlowService.reply(taskId,users,userDto.getUsername());
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 读取流程资源
     * @param pId 流程实例id
     */
    @Log("读取流程资源")
    @GetMapping("/read-resource")
    @ApiOperation(value="读取流程资源")
    public void readResource(@RequestParam String pId, HttpServletResponse response) {
        // 获取流程图
        workFlowService.getProcessImage(pId,response);
    }

    /**
     * 查看流程图
     * @param pdId 流程定义ID
     */
    @Log("查看流程图")
    @GetMapping("/viewImage/{pdId}")
    @ApiOperation(value="查看流程图")
    public void viewImage(@PathVariable String pdId, HttpServletResponse response) {
        // 获取流程图
        workFlowService.viewImage(pdId,response);
    }

    /**
     * 查看流程执行踪迹图
     * @param pdId 流程定义ID
     */
    @Log("查看流程执行踪迹图")
    @GetMapping("/viewProcessTrace/{pdId}")
    @ApiOperation(value="查看流程执行踪迹图")
    public void viewProcessTrace(@PathVariable String pdId, HttpServletResponse response) {
        // 获取流程图
        workFlowService.getProcessImage(pdId,response);
    }

    /**
     * 下载模型文件
     * @param mid 流程ID
     */
    @Log("下载bpmn文件")
    @GetMapping("/downloadBpmn/{mid}")
    @ApiOperation(value="下载bpmn文件")
    public void downloadBpmn(@PathVariable String mid, HttpServletResponse response) {
        // 获取流程图
        workFlowService.downloadBpmn(mid,response);
    }

    /**
     * 上传部署
     * @param file 资源文件
     */
    @Log("上传部署资源文件")
    @PostMapping("/deployResource")
    @ApiOperation(value="上传部署资源文件")
    public void deployResource(@RequestParam("file") MultipartFile file) {
        // 获取流程图
        workFlowService.deployResource(file);
    }

}
